Skip to content

Java 子类调用父类方法引发的血案

在 Java 中,子类可以直接调用或重写(override)父类中的非私有方法(public/default/protected)。如果重写后还想调用父类的方法,需要以super.方法名方式进行显式调用。

场景

下面假设:

子类重写父类所有的公有方法

子类调用父类方法

被调用的父类方法还在调用父类另一个公有方法

调用结果是什么样的?父类调用的方法真的是父类的吗?

实战

  • 父类方法

    java
    /**
    * 老子
    * @author Pan
    *
    */
    public class Father {
    
    	public void eat() {
    		System.out.println("老子吃饭");
    		pay();
    	}
    	
    	public void pay() {
    		System.out.println("老子付钱");
    	}
    }
  • 子类方法

    java
    /**
    * 儿子
    *
    */
    public class Son extends Father {
    	
    	@Override
    	public void eat() {
    		System.out.println("儿子陪老子吃饭");
    		super.eat();
    	}
    	
    	@Override
    	public void pay() {
    		System.out.println("儿子付钱");
    	}
    }
  • Main 方法

    java
    public class Main {
    	
    	public static void main(String[] args) {
    		
    		Father father = new Father();
    		father.eat();
    		
    		System.out.println("---------");
    		
    		Son son = new Son();
    		son.eat();
    	}
    }

父类 eat() 方法调用自己的 pay() 方法,father.eat();的结果是:

老子吃饭
老子付钱

子类 eat() 方法不同,调用的是父类的 eat() 方法,son.eat();的结果是:

儿子陪老子吃饭
老子吃饭
儿子付钱

什么?居然是“儿子付钱”。

总结

子类显式调用父类的方法时,调用的的确是父类自己的方法;如果被调用的父类方法有调用自己其他的方法,且这个方法已被子类重写,那么这个被间接调用的方法其实是子类重写后的方法。

Released under the MIT License.